package com.benshou.bsoa.service.feikong;


import com.alibaba.fastjson2.JSON;
import com.benshou.bsoa.config.FeikongProperties;
import com.benshou.bsoa.dto.feikong.req.*;
import com.benshou.bsoa.dto.feikong.res.PaymentResponse;
import com.benshou.bsoa.dto.feikong.res.ReimbursementResponse;
import com.benshou.bsoa.dto.feikong.res.SyncFeiKongCommonResponse;
import com.benshou.bsoa.sao.FeikongSao;
import com.benshou.bsoa.sao.PaymentSao;
import com.benshou.bsoa.sao.ReimbursementSao;
import com.benshou.bsoa.utils.Md5Util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.function.Function;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class FeiKongService {
    @Autowired
    private FeikongSao feikongSao;

    @Autowired
    private ReimbursementSao reimbursementSao;

    @Autowired
    private PaymentSao paymentSao;

    @Autowired
    private Md5Util md5Util;

    @Autowired
    private FeikongProperties feikongProperties;


        /**
         * 同步法人公司信息到费控云系统
         *
         * @param request 公司信息
         * @return 统一响应
         */
        public SyncFeiKongCommonResponse syncCompanyCommon(CompanyInfo request) {
            return syncToFeiKong(feikongProperties.getServiceCode().getCompany(), "companyInfo", request, feikongSao::syncCompanyCommon);
        }

        /**
         * 同步项目信息到费控云系统
         *
         * @param request 项目信息
         * @return 统一响应
         */
        public SyncFeiKongCommonResponse syncProjectCommon(ProjectInfo request) {
            return syncToFeiKong(feikongProperties.getServiceCode().getProject(), "projectInfo", request, feikongSao::syncProjectCommon);
        }


        /*
         * 查询报销单
         * @param request 请求参数
         * @return 响应结果
         */
        public ReimbursementResponse queryReimbursement(ReimbursementRequestData request) {
            PublicRequestParams publicRequestParams = buildPublicParams(feikongProperties.getServiceCode().getReimbursement());
            String jsonString = JSON.toJSONString(request);
            publicRequestParams.setData(jsonString);
            return reimbursementSao.queryReimbursementList(publicRequestParams);
        }


        /*
         * 查询付款单信息
         * @param request 请求参数
         * @return 响应结果
         */
        public PaymentResponse queryPayment(PaymentRequestData request) {
            PublicRequestParams publicRequestParams = buildPublicParams(feikongProperties.getServiceCode().getPayment());
            String jsonString = JSON.toJSONString(request);
            publicRequestParams.setData(jsonString);
            return paymentSao.queryPaymentList(publicRequestParams);
        }

        /**
         * 通用同步逻辑封装
         *
         * @param serviceName 服务名称
         * @param dataKey     数据字段名（如 companyInfo、projectInfo）
         * @param request     请求数据对象
         * @param executor    同步调用逻辑（lambda）
         * @param <T>         请求数据类型
         * @return 响应结果
         */
        private <T> SyncFeiKongCommonResponse syncToFeiKong(String serviceName, String dataKey, T request,
                                                            Function<PublicRequestParams, SyncFeiKongCommonResponse> executor) {
            PublicRequestParams publicRequestParams = buildPublicParams(serviceName);

            Map<String, Object> data = new HashMap<>();
            data.put("isASyncExecute", "");
            data.put(dataKey, List.of(request));


            try {
                String jsonData = new ObjectMapper().writeValueAsString(data);
                publicRequestParams.setData(jsonData);
                log.info("请求参数: {}", jsonData);
            } catch (JsonProcessingException e) {
                throw new IllegalArgumentException("数据序列化失败：" + e.getMessage(), e);
            }

            return executor.apply(publicRequestParams);
        }

        /**
         * 构建公共请求参数
         *
         * @param serviceName 服务名称
         * @return 公共请求参数对象
         */
        private PublicRequestParams buildPublicParams(String serviceName) {
            String timestamp = md5Util.generateTimestamp();
            String sign = md5Util.generateSign(feikongProperties.getAccount() + timestamp + feikongProperties.getKey());

            PublicRequestParams params = new PublicRequestParams();
            params.setTimestamp(timestamp);
            params.setCompid(feikongProperties.getAccount());
            params.setAccount(feikongProperties.getAccount());
            params.setService(serviceName);
            params.setResponseType("2");
            params.setSignType("MD5");
            params.setSign(sign);
            return params;
        }
}
